/* eslint-disable indent */
/*
 * @Author: HxB
 * @Date: 2023-04-27 15:16:18
 * @LastEditors: DoubleAm
 * @LastEditTime: 2024-06-14 09:44:13
 * @Description: 高级表格简单封装
 * @FilePath: \web_base\src\components\AntTable\index.tsx
 */
import { ActionType } from '@ant-design/pro-components';
import { ProTable, ProColumns } from '@ant-design/pro-table';
import { TablePaginationConfig, TableProps, Tag } from 'antd';
import { getKey } from 'js-xxx';
import React, { useEffect, useRef, useState } from 'react';

// interface AntTableProps extends TableProps {
type AntTableProps = {
  style?: React.CSSProperties;
  tableStyle?: React.CSSProperties;
  columns?: (ProColumns<any> & { defaultShow?: boolean; showSearch?: boolean })[];
  dataSource?: any[];
  select?: boolean;
  onSubmit?: (params: any) => void;
  onReset?: () => void;
  actionRef?: React.MutableRefObject<any>;
  rowKey?: string;
  pagination?: TablePaginationConfig | false;
  scroll?: { x?: number; y?: number };
  request?: (params: any) => Promise<any>;
  onRequestData?: (data: any[]) => any[];
  onSelect?: (selectedRows: any[]) => void;
  searchCollapsed?: boolean;
  [key: string]: any;
};

const AntTable: React.FC<AntTableProps> = (props) => {
  const {
    style,
    tableStyle,
    columns = [],
    dataSource = [],
    onRequestData,
    select = false,
    onSubmit,
    onReset,
    rowKey = 'xKey',
    actionRef,
    pagination = { defaultPageSize: 10, showQuickJumper: true, showSizeChanger: true }, // total
    scroll,
    request,
    onSelect,
    searchCollapsed = true,
    ...restProps
  } = props;

  const [columnsState, setColumnsState] = useState<{ [key: string]: any }>({});
  const [selectedRows, setSelectedRows] = useState<any[]>([]);
  const [collapsed, setCollapsed] = useState<boolean>(searchCollapsed);
  const [antColumns, setAntColumns] = useState<any[]>(
    columns.map((column) => ({
      title: column.title ?? column.key ?? column.dataIndex,
      key: column.key ?? column.dataIndex,
      dataIndex: column.dataIndex ?? column.key,
      search: column.search ?? (column.showSearch !== true ? false : true),
      ...column,
    })),
  );
  const [modifiedDataSource, setModifiedDataSource] = useState<any[]>([]);
  const [totalCount, setTotalCount] = useState<number>(0);
  const [currentPage, setCurrentPage] = useState<number>(1);
  const myActionRef = useRef<ActionType>();

  useEffect(() => {
    // 监听页码变化，解决 select 选择器可能未刷新的问题。
    setSelectedRows([]);
  }, [currentPage]);

  useEffect(() => {
    if (request === undefined) {
      const data = dataSource.map((item) => {
        const newItem = { ...(item ?? {}) };
        if (!newItem[rowKey]) {
          newItem[rowKey] = getKey();
        }
        return newItem;
      });
      setModifiedDataSource(data);
      setTotalCount(data.length);
    }
  }, [dataSource, rowKey, request]);

  useEffect(() => {
    if (!antColumns.length && modifiedDataSource.length > 0) {
      const autoGeneratedColumns = Object.keys(modifiedDataSource[0] || {}).map((key) => ({
        title: key,
        dataIndex: key,
        key: key,
        search: false,
      }));
      setAntColumns(autoGeneratedColumns);
    }
  }, [modifiedDataSource, antColumns]);

  const defaultColumnsState: { [key: string]: any } = {};
  useEffect(() => {
    antColumns.forEach((column) => {
      const { dataIndex, defaultShow } = column;
      defaultColumnsState[dataIndex as string] = {
        show: defaultShow !== false,
      };
    });
    setColumnsState((prevState) => ({
      ...defaultColumnsState,
      ...prevState,
    }));
  }, [antColumns]);

  const handlePostData = (data: any[]) => {
    let _tempData = data.map((item) => {
      const newItem = { ...(item ?? {}) };
      if (!newItem[rowKey]) {
        newItem[rowKey] = getKey();
      }
      return newItem;
    });
    if (onRequestData) {
      _tempData = onRequestData(_tempData);
    }
    setModifiedDataSource(_tempData);
    return _tempData;
  };

  const handleRequest = (params: any) => {
    if (request) {
      return request({
        ...params,
        // 此处还可以传递 selectKeys 参数，看需求扩展多页选择。
      })
        .then((data) => {
          setTotalCount(data.total);
          return data;
        })
        .catch((error) => {
          setTotalCount(0);
          throw error;
        });
    }
    setTotalCount(0);
    return Promise.resolve({
      data: [],
      success: true,
      total: 0,
    });
  };

  const handleSubmit = (params: any) => {
    if (onSubmit) {
      onSubmit(params);
    }
  };

  const handleReset = () => {
    if (onReset) {
      onReset();
    }
  };

  const handleRowSelectionChange = (selectedRowKeys: React.Key[], selectedRows: any[]) => {
    setSelectedRows(selectedRows);

    if (onSelect) {
      onSelect(selectedRows);
    }
  };

  const handleColumnsStateChange = (newColumnsState: { [key: string]: any }) => {
    setColumnsState(newColumnsState);
  };

  const handleCollapseChange = (newCollapsed: boolean) => {
    setCollapsed(newCollapsed);
  };

  // const selectionText = `已选择 ${selectedRows.length} 条数据`;

  return (
    <div data-component="AntTable" style={{ width: '100%', height: '100%', position: 'relative', ...(style ?? {}) }}>
      <ProTable
        style={{ ...(tableStyle ?? {}) }}
        bordered={true}
        cardBordered={false}
        ghost={false}
        // toolBarRender={() => {
        //   return [select && selectedRows.length ? <div>{selectionText}</div> : null];
        // }}
        columns={antColumns}
        dataSource={request !== undefined ? undefined : modifiedDataSource}
        rowKey={rowKey}
        pagination={pagination}
        scroll={scroll}
        request={request ? handleRequest : undefined}
        columnsState={{
          defaultValue: defaultColumnsState,
          value: columnsState,
          onChange: handleColumnsStateChange,
        }}
        onSubmit={handleSubmit}
        onReset={handleReset}
        postData={handlePostData}
        {...(restProps ?? {})}
        actionRef={actionRef ?? myActionRef}
        onChange={(pagination, filters, sorter, extra) => {
          setCurrentPage(pagination.current); // 页码变化
          if (restProps?.onChange) {
            restProps.onChange(pagination, filters, sorter, extra);
          }
        }}
        search={
          restProps.search === false
            ? false
            : {
                ...(restProps.search ?? {}),
                collapsed,
                onCollapse: handleCollapseChange,
              }
        }
        // search={{ span: 6, labelWidth: 100 }}
        rowSelection={
          select
            ? {
                ...(restProps.rowSelection ?? {}),
                // getCheckboxProps: (record) => ({
                //   disabled: selectedRows.some((item: any) => item.id === 'test-disabled'), // 根据选中项的主键值来判断是否禁用复选框
                //   checked: selectedRows.some((item: any) => item.id === record.id), // 根据选中项的主键值来判断是否选中复选框
                // }),
                onChange: handleRowSelectionChange,
                selectedRowKeys: selectedRows.map((item) => item[rowKey]),
              }
            : false
        }
        toolbar={{
          ...(restProps.toolbar ?? {}),
          actions: [
            ...(restProps?.toolbar?.actions ?? []),
            <Tag key={'totalCount'} color="black">
              共 {totalCount} 条
            </Tag>,
          ],
        }}
        options={{
          fullScreen: true,
          reload: () => {
            actionRef?.current?.reload?.();
            myActionRef?.current.reloadAndRest?.();
          },
          ...(restProps.options ?? {}),
        }}
      />
    </div>
  );
};

export default AntTable;
